package cadtoolbox.graphical;


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;

import cadtoolbox.model.OligoGraph;

import org.apache.commons.collections15.Transformer;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.Context;
import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.transform.MutableTransformer;
import edu.uci.ics.jung.visualization.transform.MutableTransformerDecorator;
import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;

public class BasicVertexRenderer<V, E> implements Renderer.Vertex<V, E> {

	public void paintVertex(RenderContext<V, E> rc, Layout<V, E> layout, V v) {
		OligoGraph<V, E> graph = (OligoGraph) layout.getGraph();
		if (rc.getVertexIncludePredicate().evaluate(
				Context.<Graph<V, E>, V> getInstance(graph, v))) {
			paintIconForVertex(rc, v, layout);
		}
	}

	/**
	 * Paint <code>v</code>'s icon on <code>g</code> at <code>(x,y)</code>.
	 */
	protected void paintIconForVertex(RenderContext<V, E> rc, V v,
			Layout<V, E> layout) {
		GraphicsDecorator g = rc.getGraphicsContext();
		boolean vertexHit = true;
		// get the shape to be rendered
		Shape shape = rc.getVertexShapeTransformer().transform(v);

		Point2D p = layout.transform(v);
		p = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p);
		float x = (float) p.getX();
		float y = (float) p.getY();
		// create a transform that translates to the location of
		// the vertex to be rendered
		AffineTransform xform = AffineTransform.getTranslateInstance(x, y);
		// transform the vertex shape with xtransform
		Shape shape1 = xform.createTransformedShape(shape);
		xform.scale(0.8, 0.8);
		Shape shape2 = xform.createTransformedShape(shape);
		vertexHit = vertexHit(rc, shape);
		// rc.getViewTransformer().transform(shape).intersects(deviceRectangle);
//		OligoGraph<V, E> graph = (OligoGraph<V, E>) layout.getGraph();
//		Transformer<V,Paint> oldfillpaint = rc.getVertexFillPaintTransformer();
//		if(graph.getSelected() != null && graph.getSelected().contains(v)){
//			rc.setVertexFillPaintTransformer(new Transformer<V,Paint>() {
//				public Paint transform(V vert){
//					return Color.BLUE;
//				}
//			});
//		}
		
		if (vertexHit) {
			if (rc.getVertexIconTransformer() != null) {
				Icon icon = rc.getVertexIconTransformer().transform(v);
				
				if (icon != null) {

					g.draw(icon, rc.getScreenDevice(), shape, (int) x, (int) y);

				} else {
					paintShapeForVertex(rc, v, shape1);
				}
			} else {
				paintShapeForVertex(rc, v, shape1);
			}
		}
//		rc.setVertexFillPaintTransformer((Transformer<V, Paint>) oldfillpaint); 
//		int i = (Integer) v;
//		if (graph.getC(i) > 0) {
//			paintShapeForVertex(rc, v, shape2);
//		}
		//System.out.println(i);
//		paintK(rc, v, graph.getK(i), (int) x + 5, (int) y + 5);
	}

	protected boolean vertexHit(RenderContext<V, E> rc, Shape s) {
		JComponent vv = rc.getScreenDevice();
		Rectangle deviceRectangle = null;
		if (vv != null) {
			Dimension d = vv.getSize();
			deviceRectangle = new Rectangle(0, 0, d.width, d.height);
		}
		MutableTransformer vt = rc.getMultiLayerTransformer().getTransformer(
				Layer.VIEW);
		if (vt instanceof MutableTransformerDecorator) {
			vt = ((MutableTransformerDecorator) vt).getDelegate();
		}
		return vt.transform(s).intersects(deviceRectangle);
	}

	protected void paintShapeForVertex(RenderContext<V, E> rc, V v, Shape shape) {
		GraphicsDecorator g = rc.getGraphicsContext();
		Paint oldPaint = g.getPaint();
		Paint fillPaint = rc.getVertexFillPaintTransformer().transform(v);
		
		if (fillPaint != null) {
			g.setPaint(fillPaint);
			g.fill(shape);
			g.setPaint(oldPaint);
		}
		Paint drawPaint = rc.getVertexDrawPaintTransformer().transform(v);
		if (drawPaint != null) {
			g.setPaint(drawPaint);
			Stroke oldStroke = g.getStroke();
			Stroke stroke = rc.getVertexStrokeTransformer().transform(v);
			if (stroke != null) {
				g.setStroke(stroke);
			}
			g.draw(shape);
			g.setPaint(oldPaint);
			g.setStroke(oldStroke);
		}

	}

	protected void paintK(RenderContext<V, E> rc, V v, double k, int x, int y) {
		JLabel label = new JLabel(String.valueOf(k));
		//System.out.println(String.valueOf(k));
		GraphicsDecorator g = rc.getGraphicsContext();
		Stroke stroke = rc.getVertexStrokeTransformer().transform(v);
		if (stroke != null) {
			g.setStroke(stroke);
		}
		g.draw(label, rc.getRendererPane(), x, y, 200, 20, true);

	}
}
